import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import router from '@/router'
import config from '@/config'

// 响应码枚举
export const ResultCode = {
  SUCCESS: 200,
  BAD_REQUEST: 400,
  UNAUTHORIZED: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  METHOD_NOT_ALLOWED: 405,
  REQUEST_TIMEOUT: 408,
  PARAM_VALID_ERROR: 4001,
  SERVER_ERROR: 500,
  SERVICE_UNAVAILABLE: 503
}

// 创建axios实例
const service = axios.create({
  baseURL: config.baseApi,
  timeout: 5000,
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
})

// 请求队列
let requestQueue = []
// 是否正在刷新token
let isRefreshing = false
// 重试队列
let retryQueue = []

/**
 * 将请求添加到队列
 * @param {Object} config 请求配置
 */
function addRequestQueue(config) {
  requestQueue.push(config.url)
}

/**
 * 从队列中移除请求
 * @param {Object} config 请求配置
 */
function removeRequestQueue(config) {
  const index = requestQueue.findIndex(url => url === config.url)
  if (index !== -1) {
    requestQueue.splice(index, 1)
  }
}

/**
 * 清空请求队列
 */
function clearRequestQueue() {
  requestQueue = []
}

/**
 * 刷新token
 * @returns {Promise}
 */
async function refreshToken() {
  try {
    const refreshToken = localStorage.getItem('refreshToken')
    if (!refreshToken) {
      throw new Error('No refresh token')
    }
    
    const response = await axios.post(`${import.meta.env.VITE_API_URL}/auth/refresh`, {
      refreshToken
    })
    
    const { token, refreshToken: newRefreshToken } = response.data.data
    localStorage.setItem('token', token)
    localStorage.setItem('refreshToken', newRefreshToken)
    
    return token
  } catch (error) {
    console.error('刷新token失败:', error)
    throw error
  }
}

// 请求拦截器
service.interceptors.request.use(
  config => {
    console.log('发送请求:', {
      url: config.url,
      method: config.method,
      data: config.data,
      params: config.params,
      headers: config.headers
    })
    
    // 检查是否存在重复请求
    if (requestQueue.includes(config.url)) {
      return Promise.reject(new Error('重复请求已被取消'))
    }
    
    // 添加请求到队列
    addRequestQueue(config)
    
    // 添加token
    const token = localStorage.getItem('token')
    if (token && !config.url.includes('/login')) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    
    // 处理GET请求缓存
    if (config.method === 'get') {
      config.params = {
        ...config.params,
        _t: Date.now() // 添加时间戳防止缓存
      }
    }
    
    return config
  },
  error => {
    console.error('请求配置错误:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 从队列中移除请求
    removeRequestQueue(response.config)
    
    console.log(`[${response.config.method.toUpperCase()}] ${response.config.url} 响应:`, response.data)
    
    const { code, data, message } = response.data
    
    // 处理文件下载
    if (response.config.responseType === 'blob') {
      return response.data
    }
    
    // 某些接口可能不会返回标准格式，直接返回数据
    if (code === undefined && response.status === 200) {
      console.log('接口返回非标准格式，直接使用响应数据', response.data)
      return response.data
    }
    
    if (code === 200) {
      if (data === undefined || data === null) {
        console.log('接口返回成功但无数据', response.data)
        return response.data // 返回整个响应体
      }
      return data
    } else {
      // 统一错误处理
      console.error('接口返回错误码', code, message)
      ElMessage.error(message || '系统错误')
      return Promise.reject(new Error(message || '系统错误'))
    }
  },
  error => {
    // 从队列中移除请求
    if (error.config) {
      removeRequestQueue(error.config)
    }
    
    if (!error.response) {
      ElMessage.error('网络错误，请检查您的网络连接')
      return Promise.reject(new Error('网络错误'))
    }
    
    const status = error.response.status
    
    switch (status) {
      case ResultCode.UNAUTHORIZED:
        ElMessage.error('未授权，请重新登录')
        localStorage.clear()
        router.push('/login')
        break
      case ResultCode.FORBIDDEN:
        ElMessage.error('没有权限访问')
        break
      case ResultCode.SERVER_ERROR:
        ElMessage.error('服务器错误')
        break
      default:
        ElMessage.error(error.response.data?.message || '请求失败')
    }
    
    return Promise.reject(error)
  }
)

export default service